#include "stdafx.h"
#include <iostream>
#include "GL/glew.h"

#include "Camera.h"
#include "core/Game.h"

void printMatrix(const glm::mat4& mat)
{
	printf("%.2g\t%.2g\t%.2g\t%.2g\n%.2g\t%.2g\t%.2g\t%.2g\n%.2g\t%.2g\t%.2g\t%.2g\n%.2g\t%.2g\t%.2g\t%.2g\n", 
		mat[0][0], mat[0][1], mat[0][2], mat[0][3],
		mat[1][0], mat[1][1], mat[1][2], mat[1][3], 
		mat[2][0], mat[2][1], mat[2][2], mat[2][3],
		mat[3][0], mat[3][1], mat[3][2], mat[3][3]);
}

Camera::Camera() : rotation(30.0f, 135.0f, 0.0f), eye(0.0f, -45.0f, -30.0f)
{
	init();
}

void Camera::init()
{
	vpDim = Game::windowDim;
	glViewport(0, 0, vpDim.x, vpDim.y); // TODO: move to Game class?

    updateView();
}

void Camera::moveForward(float dist)
{
    glm::vec3 forward(viewMatrix[0][2], viewMatrix[1][2], viewMatrix[2][2]);
    //eye += dist * forward;
	eye += dist * glm::vec3(forward.x, 0.0f, forward.z);
    updateView();
}

void Camera::moveLeft(float dist)
{
    glm::vec3 left(viewMatrix[0][0], viewMatrix[1][0], viewMatrix[2][0]);
    //eye += left * dist;
	eye += dist * glm::vec3(left.x, 0.0f, left.z);
    updateView();
}

void Camera::moveVert(float dist) {
	eye.y += dist;
	updateView();
}

void Camera::updateView()
{
    viewMatrix = glm::rotate(glm::mat4(1.0), rotation[0], glm::vec3(1.0f, 0.0f, 0.0f));
    viewMatrix = glm::rotate(viewMatrix,	 rotation[1], glm::vec3(0.0f, 1.0f, 0.0f));
    viewMatrix = glm::rotate(viewMatrix,     rotation[2], glm::vec3(0.0f, 0.0f, 1.0f));
    viewMatrix = glm::translate(viewMatrix,eye);
}

void Camera::rotateY(float angle)
{
    rotation[1] += angle;
    if(rotation[1] > 360.0f)
        rotation[1] -= 360.0f;
    else if(rotation[1] <= -360.0f)
        rotation[1] += 360.0f;

    updateView();
}

void Camera::rotateX(float angle)
{
    rotation[0] += angle;
    if(rotation[0] > 360.0f)
        rotation[0] -= 360.0f;
    else if(rotation[0] <= -360.0f)
        rotation[0] += 360.0f;

    updateView();
}

glm::vec3 Camera::getViewDirection()
{
    /*return glm::vec3(viewMatrix[2].x, viewMatrix[2].y, viewMatrix[2].z);*/

    return -glm::vec3(viewMatrix[0].z, viewMatrix[1].z, viewMatrix[2].z);
}

